#include <vector>

class IWndResizer
{
	public:
		enum DefinedResizeFlags
		{
			RF_RELATIVE_LEFT             = 0x80000000,
			RF_RELATIVE_RIGHT            = 0x40000000,
			RF_RELATIVE_TOP              = 0x20000000,
			RF_RELATIVE_BOTTOM           = 0x10000000,
			
			RF_RELATIVE                  = RF_RELATIVE_LEFT | RF_RELATIVE_RIGHT | RF_RELATIVE_TOP | RF_RELATIVE_BOTTOM,
			
			RF_ABSOLUTE_STICK_LEFT       = 0x00000001,
			RF_ABSOLUTE_STICK_RIGHT      = 0x00000002,
			RF_ABSOLUTE_STICK_TOP        = 0x00000004,
			RF_ABSOLUTE_STICK_BOTTOM     = 0x00000008,
			
			RF_RELATIVE_STICK_LEFT       = RF_RELATIVE_LEFT   | RF_ABSOLUTE_STICK_LEFT,
			RF_RELATIVE_STICK_RIGHT      = RF_RELATIVE_RIGHT  | RF_ABSOLUTE_STICK_RIGHT,
			RF_RELATIVE_STICK_TOP        = RF_RELATIVE_TOP    | RF_ABSOLUTE_STICK_TOP,
			RF_RELATIVE_STICK_BOTTOM     = RF_RELATIVE_BOTTOM | RF_ABSOLUTE_STICK_BOTTOM,
			
			RF_ABSOLUTE_STICK_LEFT_RIGHT = RF_ABSOLUTE_STICK_LEFT | RF_ABSOLUTE_STICK_RIGHT,
			RF_ABSOLUTE_STICK_TOP_BOTTOM = RF_ABSOLUTE_STICK_TOP | RF_ABSOLUTE_STICK_BOTTOM,
			
			RF_ABSOLUTE_STICK_LEFT_TOP    = RF_ABSOLUTE_STICK_LEFT | RF_ABSOLUTE_STICK_TOP,
			RF_ABSOLUTE_STICK_LEFT_BOTTOM = RF_ABSOLUTE_STICK_LEFT | RF_ABSOLUTE_STICK_BOTTOM,
			
			RF_ABSOLUTE_STICK_RIGHT_TOP    = RF_ABSOLUTE_STICK_RIGHT | RF_ABSOLUTE_STICK_TOP,
			RF_ABSOLUTE_STICK_RIGHT_BOTTOM = RF_ABSOLUTE_STICK_RIGHT | RF_ABSOLUTE_STICK_BOTTOM,
			
			RF_RELATIVE_STICK_ALL        = RF_RELATIVE_STICK_LEFT | RF_RELATIVE_STICK_RIGHT | RF_RELATIVE_STICK_TOP | RF_RELATIVE_STICK_BOTTOM,
			RF_ABSOLUTE_STICK_ALL        = RF_ABSOLUTE_STICK_LEFT | RF_ABSOLUTE_STICK_RIGHT | RF_ABSOLUTE_STICK_TOP | RF_ABSOLUTE_STICK_BOTTOM
		};
		
		enum DefinedOffsetFlags
		{
			OF_RELATIVE         = 0x00,
			OF_ABSOLUTE_LEFT    = 0x01,
			OF_ABSOLUTE_TOP     = 0x02,
			OF_ABSOLUTE_RIGHT   = 0x04,
			OF_ABSOLUTE_BOTTOM  = 0x08,
			
			OF_ABSOLUTE         = OF_ABSOLUTE_LEFT | OF_ABSOLUTE_TOP | OF_ABSOLUTE_RIGHT | OF_ABSOLUTE_BOTTOM
		};
		
		virtual bool AddItem(HWND hParentWnd, int iID, int iFlags) = 0;
		virtual bool AddItem(HWND hParentWnd, HWND hWndCtrl, int iFlags) = 0;
		virtual void Resize(DWORD w, DWORD h) = 0;
		virtual bool ResizeItem(HWND hWndCtrl, RECT *rect, DefinedOffsetFlags offset) = 0;
		virtual bool ResizeItem(HWND hParentWnd, int iID, RECT *rect, DefinedOffsetFlags offset) = 0;
};

class CWndResizer: public IWndResizer
{
	public:
		CWndResizer(HANDLE hHeap, DWORD dwMaxControls, DWORD dwInitialW, DWORD dwInitialH);
		CWndResizer(HANDLE hHeap, DWORD dwMaxControls, HWND hParentWnd);
		~CWndResizer();
		
		bool AddItem(HWND hParentWnd, int iID, int iFlags);
		bool AddItem(HWND hParentWnd, HWND hWndCtrl, int iFlags);
		void Resize(DWORD w, DWORD h);
		bool ResizeItem(HWND hWndCtrl, RECT *rect, DefinedOffsetFlags offset);
		bool ResizeItem(HWND hParentWnd, int iID, RECT *rect, DefinedOffsetFlags offset);
		
	private:
		struct RITEM
		{
			HWND hWnd;
			int iFlags;
			
			float fLeftPosRel;
			float fRightPosRel;
			float fTopPosRel;
			float fBottomPosRel;
			
			//DWORD dwOrgRight;
			//DWORD dwOrgBottom;
			RECT rcOrg;
		};
		
		void Init(DWORD dwMaxControls, DWORD dwInitialW, DWORD dwInitialH);
		inline void ResizeControl(HDWP &hDwp, RITEM *pItem, DWORD w, DWORD h, int dw, int dh);
		RITEM *GetItem(HWND hWnd);
		
		RITEM *m_pItems;
		DWORD m_dwMaxControls;
		DWORD m_dwAdded;
		
		//DWORD m_dwPrevW;
		//DWORD m_dwPrevH;
		
		DWORD m_dwOrgW;
		DWORD m_dwOrgH;
		
		HANDLE m_hHeap;
};